<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AdminLTE 3 | Vue3 | Dropdown</title>

  <!-- Google Font: Source Sans Pro -->
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  <!-- Font Awesome Icons -->
  <link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
  <!-- flag-icon-css -->
  <link rel="stylesheet" href="plugins/flag-icon-css/css/flag-icon.min.css">
  <!-- Theme style -->
  <link rel="stylesheet" href="css/adminlte.min.css">
</head>
<body>
    <div id="app">
      <lte-layout logo="img/AdminLTELogo.png" dark-mode sidebar-close header-fixed footer-fixed>
        <!-- 顶部页头 -->
        <nav class="main-header navbar navbar-expand navbar-white navbar-light" style="min-height:3.5rem;">
          <ul class="navbar-nav">
            <li class="nav-item">
              <lte-push-menu></lte-push-menu>
            </li>
          </ul>
          <ul class="navbar-nav ml-auto">
            <li class="nav-item">
              <lte-dropdown-language></lte-dropdown-language>
            </li>
            <li class="nav-item">
              <lte-fullscreen></lte-fullscreen>
            </li>
          </ul>
        </nav>

        <!-- 左侧菜单 -->
        <aside class="main-sidebar sidebar-dark-primary elevation-4">
          <a href="#" class="brand-link">
            <img src="img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">
            <span class="brand-text font-weight-light">AdminLTE 3 + Vue3</span>
          </a>
        </aside>

        <!-- 工作区 -->
        <div class="content-wrapper">
          <div class="d-flex justify-content-around align-items-center" style="height: 800px;">
            <lte-dropdown-button-example button-text="Large Button" button-style="btn-success btn-lg"></lte-dropdown-button-example>
            <lte-dropdown-button-example button-text="Small Button" type="split-button" button-style="btn-sm btn-secondary"></lte-dropdown-button-example>
            上下滚动
					</div>
        </div>

        <!-- 底部页脚 -->
        <footer class="main-footer" style="min-height:3.5rem;">
          Footer
        </footer>
      </lte-layout>
    </div>
</body>
<script src="js/vue.global.3.2.26.js"></script>
<!-- 路由 -->
<script src="js/vue-router.global.js"></script>
<!-- 动画 -->
<script src="js/animations.js"></script>
<!-- 可复用逻辑 -->
<script src="js/toggleMenu.js"></script>
<!-- 组件 -->
<script src="js/LayoutProvide.js"></script>
<script src="js/PushMenuInject.js"></script>
<script src="js/Fullscreen.js"></script>

<script>
  const Dropdown = {
    name: "LteDropdown",
    props: {
      targetRef:  Object, // elment引用
      type: {
        type: String,
        default: "link",
        validator(value) {
          // 这个值必须与下列字符串中的其中一个相匹配
          return ['link', 'button', 'split-button'].includes(value)
        }
      },
      buttonStyle: String, // 按钮样式 ex: btn-danger btn-info
    },
    setup(props, context) {
      const originRef = Vue.ref(null);

      let opened = false;
      const toggle = ()=> {
        //console.log("toggle", opened)
        if (opened) {
          props.targetRef.classList.remove("show");
          originRef.value.parentNode.classList.remove("show");
        } else {
          props.targetRef.classList.add("show");
          originRef.value.parentNode.classList.add("show");
        }
        opened = !opened;
      }

      Vue.onMounted(()=> {
        originRef.value.parentNode.classList.add("dropdown");
        document.addEventListener("click", function(event) {
          //const eventTarget = findOrigin(event.target);
          //console.log("click", originRef.value, eventTarget)
          //console.log(eventTarget !== originRef.value && eventTarget !== targetRef.value, eventTarget);
          console.log("dropdown click", originRef.value.contains(event.target))
					if (
            //!findOrigin(event.target)
            !originRef.value.contains(event.target)
          ) {
            console.log("hide dropdown")
            props.targetRef.classList.remove("show");
            originRef.value.parentNode.classList.remove("show");
            opened = false;
          }
				});

        // TODO: 组件卸载时注销事件

        function findOrigin(el) {
          //console.log(el)
          if (el === originRef.value) return el;
          let p = el.parentNode;
          if (p) {
            while(p !== document.body) {
              if (p === originRef.value) return true;
              p = p.parentNode;
            }
          }
          return false;
        }
      });

      return {
        originRef,
        toggle
      }
    },
    template: `
      <div class="dropdown" v-if="type==='link'">
        <a class="nav-link" href="#" @click.prevent="toggle" ref="originRef">
          <slot name="header"></slot>
        </a>
        <slot name="body"></slot>
      </div>
      <div class="btn-group" v-if="type==='button'">
        <button type="button" class="btn dropdown-toggle" :class="buttonStyle" @click="toggle" ref="originRef">
          <slot name="header"></slot>
        </button>
        <slot name="body"></slot>
      </div>
      <div class="btn-group" v-if="type==='split-button'">
        <button type="button" class="btn" :class="buttonStyle">
          <slot name="header"></slot>
        </button>
        <button type="button" class="btn dropdown-toggle dropdown-toggle-split" :class="buttonStyle" @click="toggle" ref="originRef">
          <span class="sr-only">Toggle Dropdown</span>
        </button>
        <slot name="body"></slot>
      </div>
    `
  }

  // 以下为具体业务相关的组件
  const DropdownLanguage = {
    name: "LteDropdownLanguage",
    setup() {
      // 将菜单的引用传给Dropdown组件，用于显示或隐藏菜单
      const bodyRef = Vue.ref(null);

      Vue.onMounted(()=> {
        
      });

      return {
        bodyRef,
      }
    },
    template: `
      <lte-dropdown :target-ref="bodyRef" type="link">
        <template v-slot:header>
          <i class="flag-icon flag-icon-cn"></i>
        </template>
        <template v-slot:body>
          <div class="dropdown-menu dropdown-menu-right p-0" ref="bodyRef">
            <a href="#" class="dropdown-item active">
              <i class="flag-icon flag-icon-us mr-2"></i> English
            </a>
            <a href="#" class="dropdown-item">
              <i class="flag-icon flag-icon-de mr-2"></i> German
            </a>
            <a href="#" class="dropdown-item">
              <i class="flag-icon flag-icon-fr mr-2"></i> French
            </a>
            <a href="#" class="dropdown-item">
              <i class="flag-icon flag-icon-es mr-2"></i> Spanish
            </a>
          </div>
        </template>
      </lte-dropdown>
    `
  }

  const DropDownButtonExample = {
    name: "LteDropdownButtonExample",
    props: {
      type: {
        type: String,
        default: "button"
      },
      buttonStyle: {
        type: String,
        default: "btn-info"
      },
      buttonText: {
        type: String,
        default: "Button"
      }
    },
    setup() {
      // 将菜单的引用传给Dropdown组件，用于显示或隐藏菜单
      const bodyRef = Vue.ref(null);

      Vue.onMounted(()=> {
        
      });

      return {
        bodyRef,
      }
    },
    template: `
      <lte-dropdown :target-ref="bodyRef" :type="type" :button-style="buttonStyle">
        <template v-slot:header>
          {{buttonText}}
        </template>
        <template v-slot:body>
          <div class="dropdown-menu dropdown-menu-right" ref="bodyRef">
            <a class="dropdown-item" href="#" @click.prevent>Action</a>
            <a class="dropdown-item" href="#" @click.prevent>Another action</a>
            <a class="dropdown-item" href="#" @click.prevent>Something else here</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="#" @click.prevent>Separated link</a>
          </div>
        </template>
      </lte-dropdown>
    `
  }

  Vue.components = Vue.components || [];
  Vue.components.push(Dropdown);
  Vue.components.push(DropdownLanguage);
  Vue.components.push(DropDownButtonExample);
</script>

<script type="text/javascript">
  const app = Vue.createApp({
    setup() {

    }
  });
  Vue.components.forEach(element => {
    app.component(element.name, element);
  });

  app.mount('#app');
</script>
</html>